package org.particlethink.auth;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.particlethink.config.RequestConfig;
import org.particlethink.model.User;
import org.particlethink.response.BaseResponse;
import org.particlethink.utils.ObjectUtils;
import org.particlethink.utils.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component("UserDetailsService")
//@ConditionalOnMissingBean(value = DevUserDetailService.class)
//@ConditionalOnExpression("#{!'dev'.equals('${spring.profiles.active}')}")
public class ProUserDetailService implements UserDetailsService {


    @Autowired
    private RequestConfig requestConfig;

    @Autowired
    private ObjectMapper objectMapper;

    private static final String getUserURL = "/material/api/getUser";

    @Override
    public UserDetails loadUserByUsername(String token) throws UsernameNotFoundException {
        try {
            HttpRequest request = HttpUtil.createGet(PathUtil.mergeUrlPaths(requestConfig.getUrl(), getUserURL));

            HttpResponse response = request.addHeaders(headers(token)).execute();
            byte[] res = response.bodyBytes();
            response.close();
            BaseResponse<Map<String, Object>> baseResponse = objectMapper.readValue(res, BaseResponse.class);
            RequestedUserInfo requestedUserInfo = ObjectUtils.instanceFromMap(baseResponse.getData(), RequestedUserInfo.class);

            DefaultUser result = new DefaultUser();
            User user = new User();

            user.setUserId(requestedUserInfo.getUserId());
            user.setUsername(requestedUserInfo.getUserName());
            user.setPhone(requestedUserInfo.getPhoneNumber());
            user.setUserType(requestedUserInfo.getUserType());
            user.setDeptName(requestedUserInfo.getDeptName());
            user.setNickName(requestedUserInfo.getNickName());
            user.setEmail(requestedUserInfo.getEmail());
            user.setToken(token);


            switch (requestedUserInfo.getUserType()) {
                case "项目":
//                    ArrayList<Integer> objects = new ArrayList<>();
//                    objects.add(Integer.parseInt(requestedUserInfo.getSupplierId()));
//                    user.setSupplierIds(objects);
                    user.setProjectIds(Optional.ofNullable(requestedUserInfo.getProjects()).orElse(new ArrayList<>()).stream().map(RequestedUserInfo.Project::getId).collect(Collectors.toList()));
                    break;
                case "公司":
                    user.setCompanyId(Optional.ofNullable(requestedUserInfo.getProjects()).orElse(new ArrayList<>()).stream().map(RequestedUserInfo.Project::getId).findFirst().orElse(null));
                    break;
                case "供应商":
                    ArrayList<Integer> objects = new ArrayList<>();
                    objects.add(Integer.parseInt(requestedUserInfo.getSupplierId()));
                    user.setSupplierIds(objects);

                    user.setProjectIds(Optional.ofNullable(requestedUserInfo.getProjects()).orElse(new ArrayList<>()).stream().map(RequestedUserInfo.Project::getId).collect(Collectors.toList()));

                    break;
            }

            result.setUser(user);

            return result;

        } catch (URISyntaxException | IOException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private String generateRequestAuthToken(String token) {
        return "Bearer " + token;
    }

    private Map<String, String> headers(String token) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", generateRequestAuthToken(token));
        return headers;
    }
}
